package GUI.calendar;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JPanel;

import officeserver.log_error.AppointmentException;
import officeserver.log_error.UserException;

import GUI.main.MainClient;
import GUI.main.dialogs.AddAppointmentDialog;

/**
 * @author mramsey3
 * 
 */
public class CalendarGridPanel extends JPanel implements MouseListener {

    private static final long serialVersionUID = 1L;
    private static final Color OFFICE_BLUE = new Color(40, 100, 220);

    /**
     * 
     */
    private int globalDayOffset;

    // globalDayOffset is the number of days between the first day of this month
    // and Jan 1, 2011
    public CalendarGridPanel(int firstDayOfMonth, int daysInMonth,
	    int globalDayOffset) {
	reset(firstDayOfMonth, daysInMonth, globalDayOffset);
    }

    /**
     * @param firstDayOfMonth
     * @param daysInMonth
     * @param globalDayOffset
     */
    public void reset(int firstDayOfMonth, int daysInMonth, int globalDayOffset) {
	this.globalDayOffset = globalDayOffset;

	removeAll();

	int rows = (firstDayOfMonth + daysInMonth) / 7 + 2;

	setLayout(new GridLayout(rows, 7));
	setBorder(BorderFactory.createLineBorder(Color.BLACK, 4));

	// add the 7 day labels
	add(new CalendarGridDayLabelPanel("SUN"));
	add(new CalendarGridDayLabelPanel("MON"));
	add(new CalendarGridDayLabelPanel("TUE"));
	add(new CalendarGridDayLabelPanel("WED"));
	add(new CalendarGridDayLabelPanel("THU"));
	add(new CalendarGridDayLabelPanel("FRI"));
	add(new CalendarGridDayLabelPanel("SAT"));

	// add the actual days
	boolean exists = false;
	for (int day = 0; day < (rows - 1) * 7; day++) {
	    boolean[][] schedule = null;
	    try {
		schedule = MainClient.getConnection().selfCheckCalendar(
			globalDayOffset + day);
	    } catch (Exception e) {
		e.printStackTrace();
	    }
	    int count = 0;
	    boolean booked = false;
	    for (int i = 0; i < schedule.length; i++) {
		try {
		    for (int j = 0; j < MainClient.getConnection().getDoctors()
			    .size(); j++) {
			if (!schedule[i][j]) {
			    count++;
			}
		    }
		} catch (UserException e) {
		    e.printStackTrace();
		}
		catch (AppointmentException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (ClassNotFoundException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    }
	    try {
		if (count >= schedule.length
			* MainClient.getConnection().getDoctors().size()
			&& ((MainClient.getConnection().getDoctors().size() * schedule.length) > 0)) {
		    booked = true;
		}
	    } catch (UserException e) {
		e.printStackTrace();
	    }
		catch (AppointmentException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (ClassNotFoundException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	    exists = day >= firstDayOfMonth
		    && day < firstDayOfMonth + daysInMonth;
	    CalendarGridCellPanel cell = new CalendarGridCellPanel(day
		    - firstDayOfMonth, exists, booked);
	    if (exists) {
		cell.addMouseListener(this);
	    }
	    add(cell);
	}
    }

    /**
     * @param cell
     */
    public void updateCell(CalendarGridCellPanel cell) {
	boolean[][] schedule = null;
	try {
	    schedule = MainClient.getConnection().selfCheckCalendar(
		    globalDayOffset + cell.getDayOfMonth());
	} catch (Exception e) {
	    e.printStackTrace();
	}
	int count = 0;
	boolean booked = false;
	for (int i = 0; i < schedule.length; i++) {
	    try {
		for (int j = 0; j < MainClient.getConnection().getDoctors()
			.size(); j++) {
		    if (!schedule[i][j]) {
			count++;
		    }
		}
	    } catch (UserException e) {
		e.printStackTrace();
	    }
		catch (AppointmentException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (IOException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (ClassNotFoundException e)
		{
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	try {
	    if (count >= schedule.length
		    * MainClient.getConnection().getDoctors().size()) {
		booked = true;
	    }
	} catch (UserException e) {
	    e.printStackTrace();
	}
	catch (AppointmentException e)
	{
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	catch (IOException e)
	{
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	catch (ClassNotFoundException e)
	{
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
	cell.setBooked(booked);
    }

    /**
     * @author mramsey3
     * 
     */
    private class CalendarGridDayLabelPanel extends JPanel {

	private static final long serialVersionUID = 1L;

	private JLabel text;

	/**
	 * @param label
	 */
	public CalendarGridDayLabelPanel(String label) {
	    setLayout(new GridBagLayout());
	    setBackground(OFFICE_BLUE);
	    setBorder(BorderFactory.createMatteBorder(0, 0, 0, 2, Color.WHITE));

	    text = new JLabel(label);
	    text.setForeground(Color.WHITE);
	    add(text);
	}

	public void paintComponent(Graphics g) {
	    super.paintComponent(g);
	    int fontSize = Math.min(Math.min(30, getHeight() - 4),
		    getWidth() / 3);
	    Font dayLabelFont = new Font(Font.SANS_SERIF, Font.BOLD, fontSize);
	    text.setFont(dayLabelFont);
	}

    }

    public void mouseReleased(MouseEvent e) {
	if (e.getClickCount() == 2) {
	    int globalDayCount = globalDayOffset
		    + ((CalendarGridCellPanel) e.getSource()).getDayOfMonth();
	    if (!((CalendarGridCellPanel) e.getSource()).isBooked()) {

		AddAppointmentDialog aad = new AddAppointmentDialog(
			globalDayCount, (CalendarGridCellPanel) e.getSource(),
			this);
		aad.setVisible(true);
	    }
	}
    }

    public void mouseClicked(MouseEvent e) {
    }

    public void mousePressed(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }
}
